<?php

class node
{
	public $_db         = null;
    public $_id        = 'id';
    public $_parent_id = 'parent_id';
    public $_lft       = 'lft';
    public $_rgt       = 'rgt';
    public $_table      = '#__groups';

	function __construct($db, $table)
	{
        if(!$table || !$db)
            exit;

        $this->_table = $table;
		$this->_db = $db;
	}

	/**
	 * 
	 * @access private 
	 * @return void 
	 */
	function addNode($parent_id = 0, $name)
	{
        $lft = 0;
        $rgt = 1;
		if($parent_id > 0) {
			$res = $this->checkNode($parent_id);
			//取得父类的左值,右值
			$lft = (int)$res['lft'];
			$rgt = (int)$res['rgt'];
			$this->_db->query("UPDATE `{$this->_table}` SET `lft` = `lft`+2 WHERE `lft` > $rgt");
			$this->_db->query("UPDATE `{$this->_table}` SET `rgt` = `rgt`+2 WHERE `rgt` >= $rgt");
		} 
		//插入
		if ($this->_db->query("INSERT INTO `{$this->_table}` SET `parent_id` = '$parent_id', `lft` = '$rgt', `rgt` = '$rgt'+1, `name` = '$name'"))
		{
			return true;
		}
		else
		{
			return false;
		} 
	} 

	/**
	 * 编辑类，修改 parent_id 值后调用递归重建左右值
	 * 
	 * @access private 
	 * @return void 
	 */
	function editNode($id, $parent_id)
	{
        $res = $this->_db->query("UPDATE `{$this->_table}` SET `parent_id` = $parent_id WHERE `{$this->_id}` = $id ");
        if($res)
        {
            //重建整个树左右值
            $this->rebuildTree();
            return true;
        }
        return false;
	} 

	/**
	 * 取得被删除类别的左右值,检测是否有子类,如果有就一起删除
     *
	 * @access private 
	 * @return void
	 */
	function deleteNode($id)
	{ 
		$res = $this->checkNode($id);
		$lft = (int)$res['lft'];
		$rgt = (int)$res['rgt'];
		//执行删除
		if ($this->_db->query("DELETE FROM `{$this->_table}` WHERE `lft` >= $lft AND `rgt` <= $rgt"))
		{
			$value = (int)$rgt - $lft + 1;
			//更新左右值
			$this->_db->query("UPDATE `{$this->_table}` SET `lft` = `lft` - $value WHERE `lft` > $lft");
			$this->_db->query("UPDATE `{$this->_table}` SET `rgt` = `rgt` - $value WHERE `rgt` > $rgt");
			return true;
		} 
		else
		{
			return false;
		} 
	} 

	/**
	 * 1,所有子类,不包含自己;2包含自己的所有子类;3不包含自己所有父类4;包含自己所有父类
	 * 
	 * @access private 
	 * @return void 
	 */
	function getNodeAll($id, $type = 1)
	{
		$res = $this->checkNode($id);
		$lft = $res['lft'];
		$rgt = $res['rgt'];
		$sql = "SELECT * FROM `{$this->_table}` WHERE ";
		switch ($type)
		{
			case "1":
				$condition = "`lft` > $lft AND `rgt` < $rgt";
				break;
			case "2":
				$condition = "`lft` >= $lft AND `rgt` <= $rgt";
				break;
			case "3":
				$condition = "`lft` < $lft AND `rgt` > $rgt";
				break;
			case "4":
				$condition = "`lft` <= $lft AND `rgt` >= $rgt";
				break;
			default :
				$condition = "`lft` > $lft AND `rgt` < $rgt";
		} 
		$sql .= $condition . " ORDER BY `lft` ASC";
		$res = $this->_db->fetch_array($sql);
		return $res;
	} 

	/**
	 * 取得直属父类
	 * 
	 * @access private 
	 * @return void 
	 */
	function getParent($id)
	{
		$parent = $this->getNodeAll($id, 3);
		return $parent;
	} 

	/**
	 * 检测父类id是否存在
     *
	 * @access private 
	 * @return void 
	 */
	function checkNode($id)
	{ 
		$record = $this->_db->fetch_record("SELECT * FROM `{$this->_table}` WHERE `{$this->_id}` = $id ");
		if (count($record) > 0)
		{
            return $record;
		}
        die('没有节点数据');
        //return null;
	} 
    
    /**
     * 重建树形结构的左右值
     *
	 * @access private
	 * @return void 
     */
	function rebuildTree($parent_id = 0, $left = 0)
	{ 
		//左值 +1 是右值
		$right = $left + 1;
		//获得这个节点的所有子节点
		$res = $this->_db->execute("SELECT `{$this->_id}` FROM `{$this->_table}` WHERE `parent_id` = '" . $parent_id . "'");
        if(is_array($res)) 
        {
            foreach($res as $row) {
                //每个递归执行这个函数
                //这个节点的子
                //$right 是当前的右值，这是由 rebuildTree 函数递增
                $right = $this->rebuildTree($row[$this->_id], $right);
            }
        }
		$this->_db->execute("UPDATE `{$this->_table}` SET `lft` = '" . $left . "', `rgt` = '" . $right . "' WHERE `{$this->_id}` = '" . $parent_id . "' "); 
		//返回此节点的右值+1
		return $right + 1;
	} 

	/**
	 * 输出树形层数数据
     *
	 * @access private 
	 * @return array ($catagoryarray,$deep)
	 */
	function nodeTree($id = 0)
	{
		$output = array();
        $res = $this->checkNode($id);
		if(is_array($res))
		{
			$right = array();
			$res = $this->_db->fetch_array(" SELECT * FROM `{$this->_table}` WHERE `lft` BETWEEN '".$res['lft']."' AND '".$res['rgt']."' ORDER BY lft ASC");
			foreach($res as $row)
			{
				if(count($right) > 0)
				{
					while($right[count($right)-1] < $row['rgt'])
					{
						array_pop($right);
					} 
				}
				$output[] = array('sort' => $row, 'deep' => count($right));
				$right[] = $row['rgt'];
			} 
		} 
		return $output;
	} 

    /**
     * 获取树所有列表
     */
    function getNodeTreeAll()
    {
        $res = $this->_db->fetch_array(
            "SELECT a.{$this->_id} AS value, a.name AS text, a.parent_id, COUNT(DISTINCT b.{$this->_id}) AS level 
            FROM #__catagory AS a 
            LEFT JOIN #__catagory AS b ON (a.lft > b.lft AND a.rgt < b.rgt) 
            GROUP BY a.{$this->_id} 
            ORDER BY a.lft ASC" 
        );
        return $res;
    }
    
    //返回当前节点的完整路径
	public function getSinglePath($id = 0)
	{
        $sql = "
            SELECT parent.* 
            FROM #__catagory AS node, #__catagory AS parent 
            WHERE node.lft between parent.lft AND parent.rgt AND node.{$this->_id} = '{$id}' 
            ORDER BY parent.lft";
		return $this->_db->fetch_array($sql);
	}

	/**
	 * 
	 * @access private 
	 * @return void 
	 */
	function getRootId()
	{
		$record = $this->_db->fetch_record("SELECT * FROM `{$this->_table}` WHERE parent_id = 0 ");
		if (count($record) > 0)
		{
			return $record[$this->_id];
		}
        return 0;
	}
}